<?php
/**
 * 文本图片音频过滤服务-数美Next Data
 * zhouliang
 * 2020.09.26
 */

namespace App\Services\Tools;

use App\Repositories\LogRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

define('SM_API_TEXT_HOST', 'http://api-text-sh.fengkongcloud.com');
define('SM_API_IMG_HOST', 'http://api-img-sh.fengkongcloud.com');
define('SM_API_AUDIO_HOST', 'http://api-audio-sh.fengkongcloud.com');
define('SM_API_AUDIO_STREAM_HOST', 'http://api-audiostream-sh.fengkongcloud.com');
define('SM_API_VIDEO_HOST', 'http://api-video-sh.fengkongcloud.com');

define('TEXT_URI', '/v2/saas/anti_fraud/text');
define('IMG_URI', '/v2/saas/anti_fraud/img');
define('IMGS_URI', '/v2/saas/anti_fraud/imgs');
define('VIDEO_URI', '/v2/saas/anti_fraud/video');
define('AUDIO_URI', '/v2/saas/anti_fraud/audio');
define('AUDIO_STREAM_URI', '/v2/saas/anti_fraud/audiostream');
define('FINISH_AUDIO_STREAM_URI', '/v2/saas/anti_fraud/finish_audiostream');

class FilterService
{
    public static $riskLevel = '';
    static public $accessKey;

    /*----------------------------------天网产品(渠道防欺诈)------------------------------------*/

    const TW_HOST = 'http://api-skynet-bj.fengkongcloud.com/v4/event';


    public function __construct()
    {
        $this->accessKey = env('SHUMEI_ACCESS_KEY');
    }

    //天网监控
    static function checkUsers($device_id, $box_id, $channel_no)
    {
        $client_info = getClientInfo();
        $dataParams['ip'] = Request::capture()->ip();
//        $dataParams['tokenId'] = 1000;
        $dataParams['isTokenSeperate'] = 0;
        $dataParams['timestamp'] = get_microtime();
        $dataParams['deviceId'] = $box_id;
        $dataParams['os'] = $client_info['clientType'];
        $dataParams['appVersion'] = $client_info['appVersion'];
//        $dataParams['extra'] = [
//            'advertisingId' => '869213047926091',
//            'apputm' => 'pls'
//        ];
        $dataParams['advertisingId'] = $device_id;
        $dataParams['apputm'] = $channel_no;
        $postData['data'] = $dataParams;
        $postData['accessKey'] = env('SHUMEI_ACCESS_KEY');
        $postData['appId'] = 'default';
        $postData['eventId'] = 'activation';


        $url = self::TW_HOST; // 设置请求url地址

        $response = self::Post($url, $postData); // 发起接口请求
        $resJson = json_decode($response, true);

        /**
         * 接口会返回code， code=1100 时说明请求成功，根据不同的 riskLevel 风险级别进行业务处理
         * 当 code!=1100 时，如果是 1902 错误，需要检查参数配置
         * 其余情况需要根据错误码进行重试或者其它异常处理
         */
        $data = [];
        if ($resJson["code"] == 1100) {
            if ($resJson["riskLevel"] == "PASS") {
                $data = [
                    'result'      => 1,
                    'result_info' => '有效流量',
                ];
            } else {
                $data = [
                    'result'      => 2,
                    'result_info' => isset($resJson['detail']['description']) ? $resJson['detail']['description'] : '',
                ];
            }
            $data['status'] = 2;
            $data['request_id'] = $resJson['requestId'];
        } else {
            $data = [
                'status'      => 1,
                'result'      => 0,
                'result_info' => '接口调用失败',
                'request_id'  => '',
            ];
        }

        return $data;
    }


    // 验证用户注册
    static public function checkUserRegister($userId, $boxId, $phone = '')
    {
        $postData['accessKey'] = env('SHUMEI_ACCESS_KEY');
        $postData['appid'] = 'default';
        $postData['eventId'] = 'register';
        $clientInfo = getClientInfo();
        $ip = Request::capture()->ip();
        $clientType = $clientInfo['clientType'];
        $appVersion = $clientInfo['appVersion'];
        $dataParams = [];
        $dataParams['tokenId'] = (string) $userId;       // 设置tokenId, 由客户提供
        $dataParams['isTokenSeperate'] = 0; // 是否区分账号体系同公司不同 app 接入，未统一账号体系，不同 app，不同用户出现相同账号，需要区分账号体系，0，不区分，1，区分。
        $dataParams['ip'] = $ip;
        if(!empty($boxId)){
            $dataParams['deviceId'] = (string)$boxId;
        }
        $dataParams['timestamp'] = time();
        $dataParams['os'] = $clientType;
        $dataParams['appVersion'] = $appVersion;
        if(!empty($phone)){
            $dataParams['phone'] = md5($phone);
            $dataParams['countryCode'] = "0086";
        }
        $postData['data'] = $dataParams;
        $url = self::TW_HOST; // 设置请求url地址
        $response = self::Post($url, $postData); // 发起接口请求
        $resJson = json_decode($response, true);
        if ($resJson["code"] == 1100) {
            if ($resJson["riskLevel"] == "REJECT") {
//                return $resJson
                return $resJson['detail']['description'] ?? json_encode($resJson['detail']);
//                return true;
            }
        }

        return false;
    }



    /*---------------------------------------天净产品------------------------------------------*/
    //公共过滤
    public static function checkCommon($text, $tokenId, $channel = "COMMENT")
    {
        $dataParams['tokenId'] = $tokenId;
        $dataParams['text'] = $text;
        $dataParams['channel'] = $channel;

        return self::checkText($dataParams);
    }

    //过滤视频
    public static function checkMicroBlogVideo($url, $tokenId, $video_id = '')
    {
        $dataParams['tokenId'] = $tokenId;
        $dataParams['url'] = $url;

//        $dataParams['id'] = $video_id;
        return self::checkVideo($dataParams);
    }


    //过滤昵称
    public static function checkNickname($text, $user_id)
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'NICKNAME';

        return self::checkText($dataParams);
    }

    //过滤动态
    public static function checkMicroblog($text, $user_id)
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'microblog';

        return self::checkText($dataParams);
    }

    //过滤查询关键字
    public static function checkQuery($text, $user_id = 0)
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'QUERY';

        return self::checkText($dataParams);
    }

    //过滤个性签名
    public static function checkSignature($text, $user_id, $nickname = '')
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'SIGNATURE';
        if ($nickname) {
            $dataParams['nickname'] = $nickname;
        }

        return self::checkText($dataParams);
    }

    //过滤私聊
    public static function checkChat($text, $user_id, $user_id_to)
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'message';
        $dataParams['receiveTokenId'] = $user_id_to;

        return self::checkText($dataParams);
    }

    //过滤公屏消息
    public static function checkGroupChat($text, $user_id, $room_id)
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'GROUP_CHAT';
        $dataParams['room_id'] = $room_id;

        return self::checkText($dataParams);
    }

    //过滤房间名称
    public static function checkRoomName($text, $room_code)
    {
        $dataParams['tokenId'] = $room_code;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'COMMENT';
        $dataParams['room'] = $room_code;

        return self::checkText($dataParams);
    }

    //过滤房间玩法
    public static function checkRoomPlaying($text, $room_code)
    {
        $dataParams['tokenId'] = $room_code;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'COMMENT';
        $dataParams['room'] = $room_code;

        return self::checkText($dataParams);
    }

    //过滤房间欢迎语
    public static function checkRoomGreeting($text, $room_code)
    {
        $dataParams['tokenId'] = $room_code;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'COMMENT';
        $dataParams['room'] = $room_code;

        return self::checkText($dataParams);
    }

    //过滤拍卖内容
    public static function checkAuctionContent($text, $user_id)
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'COMMENT';

        return self::checkText($dataParams);
    }

    //过滤歌名
    public static function checkSongName($text, $user_id)
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'COMMENT';

        return self::checkText($dataParams);
    }

    //过滤原唱姓名
    public static function checkSingerName($text, $user_id)
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'COMMENT';

        return self::checkText($dataParams);
    }

    //过滤单人房抽奖奖品名称
    public static function checkRewardName($text, $user_id)
    {
        $dataParams['tokenId'] = $user_id;
        $dataParams['text'] = $text;
        $dataParams['channel'] = 'COMMENT';

        return self::checkText($dataParams);
    }

    private static function checkText($dataParams, $eventId = "")
    {
        if (!isset($dataParams['channel']) || $dataParams['channel'] == ''){
            $dataParams['channel'] = 'image';
        }
        $dataParams['ip'] = Request::capture()->ip();

        $postData['data'] = $dataParams;
        $logRtx = new LogRepository("shumei-request");
        $logRtx->log("SHUMEI_ACCESS_KEY",  env('SHUMEI_ACCESS_KEY'));
        $logRtx->File();
        $postData['accessKey'] = env('SHUMEI_ACCESS_KEY');
        $postData['type'] = 'SOCIAL';
        $postData["eventId"] = $eventId;
        $url = SM_API_TEXT_HOST.TEXT_URI; // 设置请求url地址

        $response = self::Post($url, $postData); // 发起接口请求
        $resJson = json_decode($response, true);
        /**
         * 接口会返回code， code=1100 时说明请求成功，根据不同的 riskLevel 风险级别进行业务处理
         * 当 code!=1100 时，如果是 1902 错误，需要检查参数配置
         * 其余情况需要根据错误码进行重试或者其它异常处理
         */
        if (isset($resJson["code"]) && $resJson["code"] == 1100) {

            self::$riskLevel = $resJson["riskLevel"] ?? '';

            if ($resJson["riskLevel"] !== "PASS") {
                return true;
            }
        }

        return false;
    }

    // 获取真实ip  因为负载均衡

    public static function getClientRealIP()
    {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $user_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif (isset($_SERVER['HTTP_X_REAL_IP'])) {
            $user_ip = $_SERVER['HTTP_X_REAL_IP'];
        } elseif (getenv("REMOTE_ADDR")) {
            $user_ip = getenv("REMOTE_ADDR");
        } elseif (getenv("HTTP_CLIENT_IP")) {
            $user_ip = getenv("HTTP_CLIENT_IP");
        } else {
            $user_ip = "unknown";
        }
        return $user_ip;
    }

    /**
     * 检查视频
     * @param $dataParams
     * @return bool
     */
    private static function checkVideo($dataParams)
    {
        $dataParams['ip'] = self::getClientRealIP();
        $postData['data'] = $dataParams;
        $postData['accessKey'] = self::$accessKey;
//        $postData['btId'] = '';

        $url = SM_API_VIDEO_HOST.VIDEO_URI; // 设置请求url地址

        $response = self::Post($url, $postData); // 发起接口请求
        $resJson = json_decode($response, true);

        /**
         * 接口会返回code， code=1100 时说明请求成功，根据不同的 riskLevel 风险级别进行业务处理
         * 当 code!=1100 时，如果是 1902 错误，需要检查参数配置
         * 其余情况需要根据错误码进行重试或者其它异常处理
         */
        if ($resJson["code"] == 1100) {
            if ($resJson["riskLevel"] !== "PASS") {
                return true;
            }
        }

        return false;
    }


    //过滤头像
    public static function checkHeadPicture($image, $user_id, $channel = 'headimg')
    {
        $dataParams['tokenId'] = (string) $user_id;
        $dataParams['img'] = $image;
        $dataParams['channel'] = $channel;

        return self::checkImage($dataParams);
    }
    //过滤头像
    public static function checkHeadPictureMulti($images, $user_id, $channel = 'headimg')
    {
        $dataParams['tokenId'] = (string) $user_id;
        $dataParams['imgs'] = $images;
        $dataParams['channel'] = $channel;

        $postData['accessKey'] = self::$accessKey;
        $postData['type'] = 'POLITICS_PORN_AD_BEHAVIOR';
        $postData['data'] = $dataParams;
        $url = SM_API_IMG_HOST.IMGS_URI;          // 设置请求url地址
        $response = self::Post($url, $postData); // 发起接口请求
        $resJson = json_decode($response, true);

        if (isset($resJson["code"]) && $resJson["code"] == 1100) {
            return $resJson;
        }
        return [];
    }

    public static function checkGroupText($groupId, $userId, $text): bool
    {
        $eventId = "GROUP_CHAT";
        $dataParams['tokenId'] = $userId;
        $dataParams['text'] = $text;
        $dataParams['extra'] = [
            'room' => $groupId,
        ];
        return self::checkText($dataParams, $eventId);
    }

    public static function checkGroupImage($groupId, $userId, $image)
    {
        $eventId = "GROUP_CHAT";
        $dataParams['tokenId'] = (string)$userId;
        $dataParams['img'] = $image;
        $dataParams['extra'] = [
            'room' => $groupId,
        ];
        return self::checkImage($dataParams, $eventId);
    }

    //过滤图片
    public static function checkImage($dataParams, $eventId = "", $is_multi = false)
    {
        $postData['accessKey'] = env('SHUMEI_ACCESS_KEY');
        $postData['type'] = 'POLITICS_PORN_AD_BEHAVIOR';

        if(!isset($dataParams['channel']) || $dataParams['channel'] == '' || !in_array($dataParams['channel'],['message','image','headimg','article'])){
            $dataParams['channel'] = 'message';
        }
        $dataParams['ip'] = self::getClientRealIP();
        $postData['data'] = $dataParams;
        $postData["eventId"] = $eventId;
        $img_uri = $is_multi ? IMGS_URI : IMG_URI;
        $url = SM_API_IMG_HOST.$img_uri;          // 设置请求url地址
        $response = self::Post($url, $postData); // 发起接口请求
        $resJson = json_decode($response, true);

        /**
         * 接口会返回code， code=1100 时说明请求成功，根据不同的 riskLevel 风险级别进行业务处理
         * 当 code!=1100 时，如果是 1902 错误，需要检查参数配置
         * 其余情况需要根据错误码进行重试或者其它异常处理
         */
        if ($resJson["code"] == 1100) {
            self::$riskLevel = $resJson["riskLevel"] ?? '';
            if ($resJson["riskLevel"] !== "PASS") {
                return true;
            }
        }

        return false;
    }

    //过滤音频 异步回调返回结果 todo
    public function checkAudio($audio, $user_id = 0, $ext = [])
    {
    }

    //返回request_id
    public static function checkRoomAudioStream($room_id, $user_id, $pit_number = 0)
    {
        $stream_id = $room_id.'_'.$user_id;
        $dataParams['streamType'] = 'ZEGO';
        $tokenId = self::getZegoToken();
        $dataParams['zegoParam'] = [
            'tokenId'  => (string) $tokenId,
            'streamId' => $stream_id,
            'roomId'   => (string) $room_id,
            'testEnv'  => false,
        ];
        $dataParams['audioName'] = $stream_id.'_'.$pit_number;
        $dataParams['room'] = (string) $room_id;
        $dataParams['tokenId'] = (string) $user_id;
        $dataParams['channel'] = 'VOICE_ROOM';

        return self::checkAudioStream($dataParams, $stream_id);
    }

    //过滤音频 异步回调返回结果
    public static function checkAudioStream($dataParams, $stream_id)
    {
        $postData['accessKey'] = self::$accessKey;
        $postData['type'] = 'AD_PORN_POLITICAL_MOAN';
        $postData['btId'] = $stream_id;
        $postData['callback'] = trim(env('APP_URL'), '/') . '/callback/shumei/stream';
        $postData['data'] = $dataParams;
        $url = SM_API_AUDIO_STREAM_HOST.AUDIO_STREAM_URI;             // 设置请求url地址
        $result = self::Post($url, $postData);                        // 发起接口请求
        $result = json_decode($result, true);
        Log::info('shumei-streamid-'.$stream_id, $result);
        $request_id = $result['requestId'] ?? '';

        return $request_id;
    }

    //关闭音频流过滤
    public static function finishAudioStream($request_id)
    {
        $postData['accessKey'] = self::$accessKey;
        $postData['requestId'] = $request_id;
        $url = SM_API_AUDIO_STREAM_HOST.FINISH_AUDIO_STREAM_URI;             // 设置请求url地址
        self::Post($url, $postData);                                         // 发起接口请求
    }

    // todo
    public static function getZegoToken()
    {
        $token = app('redis')->get('zego:token');
        if ($token) {
            return $token;
        }
        $zego_appid = (int) env('ZEGO_APPID');

        $access_token_url = 'https://liveroom'.$zego_appid.'-api.zego.im/cgi/token';
        $token_result = self::Post($access_token_url, [
            'version' => 1,
            'seq'     => time(),
            'app_id'  => $zego_appid,
            'token'   => self::createZegoToken(),
        ]);
        $result = json_decode($token_result, true);
        $access_token = $result['data']['access_token'] ?? '';
        $url = 'https://liveroom'.$zego_appid.'-api.zego.im/cgi/identifytoken';
        $token_result = self::Post($url, ['access_token' => $access_token]);
        $token_result = json_decode($token_result, true);
        $token = $token_result['data']['identify_token'] ?? '';
        if ($token) {
            app('redis')->setex('zego:token', 3500, $token);
        }

        return $token;
    }

    public static function createZegoToken()
    {
        $zego_appid = env('ZEGO_APPID');
        $current_time = time();                                    //获取当前时间
        $expired_time = $current_time + 86400;                     //过期时间，单位：秒
        $app_id = $zego_appid;                                     // Int类型,这里填写各自分配的appid
        $server_app_secret = env('ZEGO_SERVER_SECRET');            // 这里填写对应的ServerSecret
        $nonce = str_random();                                     //自定义的随机数
        $origin = $app_id.$server_app_secret.$nonce.$expired_time;
        $hash = md5($origin);
        $token = [
            'ver'     => 1,
            'hash'    => $hash,
            'nonce'   => $nonce,
            'expired' => $expired_time,
        ];
        $token = json_encode($token);
        $encode_token = base64_encode($token);

        return $encode_token;
    }


    public static function Get($url)
    {
        //初始化
        $ch = curl_init();
        //设置选项，包括URL
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //执行并获取HTML文档内容
        $output = curl_exec($ch);
        //释放curl句柄
        curl_close($ch);

        //返回结果
        return $output;
    }

    public static function Post($url, $postData)
    {
        $data_string = json_encode($postData, JSON_UNESCAPED_SLASHES);
        $ch = curl_init();
        // 设置超时时间
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // post数据
        curl_setopt($ch, CURLOPT_POST, 1);
        // post的变量
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER,
            ['Content-Type: application/json; charset=utf-8', 'Content-Length: '.strlen($data_string)]);
        $output = curl_exec($ch);
        curl_close($ch);

        //返回结果
        return $output;
    }
}

